<?php

namespace Wxwork;

use Exception;
use GuzzleHttp\Psr7\Utils;
use Wxwork\Http\API;
use Wxwork\Http\Request;
use Wxwork\Http\Response;

/**
 * 服务商接口
 */
class ServiceCorp
{

    private $corpId;

    private $suiteId;

    private $secret;

    private $logsDir;

    private $request;

    public function __construct(array $config)
    {
        $this->corpId = $config['corpId'] ?? '';
        $this->suiteId = $config['suiteId'] ?? '';
        $this->secret = $config['secret'] ?? '';
        $this->logsDir = $config['logsDir'] ?? '';

        $this->request = new Request($config);
    }


    /**
     * 获取第三方应用凭证
     * @param string $suiteTicket
     * @return string
     * @throws Exception
     */
    public function getSuiteToken(string $suiteTicket): string
    {
        $param = [
            'suite_id' => $this->suiteId,
            'suite_secret' => $this->secret,
            'suite_ticket' => $suiteTicket
        ];

        $response = $this->request->request(API::$GET_SUITE_TOKEN, 'POST', $param);

        if ($response->isSuccess()) {
            return $response->getBody()['suite_access_token'] ?? '';
        } else {
            throw new Exception($response->getError());
        }
    }

    /**
     * 获取企业永久授权码
     * @param string $suiteAccessToken
     * @param string $tempAuthCode
     * @return void
     */
    public function getPermanentCode(string $suiteAccessToken, string $tempAuthCode): Response
    {
        $param = ["auth_code" => $tempAuthCode];

        return $this->request->request(API::$GET_PERMANENT_CODE . $suiteAccessToken, 'POST', $param);
    }


    public function getAuthInfo(string $suiteAccessToken, string $authCorpId, string $permanentCode)
    {
        $param = [
            "auth_corpid" => $authCorpId,
            'permanent_code' => $permanentCode
        ];

        return $this->request->request(API::$GET_AUTH_INFO . $suiteAccessToken, 'POST', $param);
    }

    /**
     * access_token的获取
     * @param string $authCorpId
     * @param string $permanentCode
     * @return string
     * @throws Exception
     */
    public function getAccessToken(string $authCorpId, string $permanentCode): string
    {
        $param = [
            "corpid" => $authCorpId,
            'corpsecret' => $permanentCode
        ];
        $response = $this->request->request(API::$ACCESS_TOKEN, 'GET', $param);

        if ($response->isSuccess()) {
            return $response->getBody()['access_token'] ?? '';
        } else {
            throw new Exception($response->getError());
        }
    }

    /**
     * 三方应用access_token的获取
     * @param string $suiteAccessToken
     * @param string $authCorpId
     * @param string $permanentCode
     * @return string
     * @throws Exception
     */
    public function getAccessToken3rd(string $suiteAccessToken, string $authCorpId, string $permanentCode): string
    {
        $getParam = [
            'suite_access_token' => $suiteAccessToken
        ];

        $param = [
            "auth_corpid" => $authCorpId,
            "permanent_code" => $permanentCode
        ];

        $response = $this->request->request(API::$ACCESS_TOKEN_3RD . '?' . http_build_query($getParam), 'POST', $param);

        if ($response->isSuccess()) {
            return $response->getBody()['access_token'] ?? '';
        } else {
            throw new Exception($response->getError());
        }
    }

    /**
     * 获取企业 jsapi_ticket
     * @param string $accessToken
     * @return mixed|string
     * @throws Exception
     */
    public function getJsapiTicket(string $accessToken) :string
    {
        $getParam = [
            'access_token' => $accessToken
        ];

        $response = $this->request->request(API::$GET_JSAPI_TICKET, 'GET', $getParam);

        if ($response->isSuccess()) {
            return $response->getBody()['ticket'] ?? '';
        } else {
            throw new Exception($response->getError());
        }
    }

    /**
     * 获取应用 jsapi_ticket
     * @param string $accessToken
     * @return mixed|string
     * @throws Exception
     */
    public function getAgentJsapiTicket(string $accessToken)
    {
        $getParam = [
            'access_token' => $accessToken,
            'type'=> 'agent_config'
        ];

        $response = $this->request->request(API::$GET_AGENT_JSAPI_TICKET, 'GET', $getParam);

        if ($response->isSuccess()) {
            return $response->getBody()['ticket'] ?? '';
        } else {
            throw new Exception($response->getError());
        }
    }


    /**
     * 读取成员
     * @param string $accessToken
     * @param string $userId
     * @return array
     * @throws Exception
     */
    public function getUser(string $accessToken, string $userId): array
    {
        $param = [
            'access_token' => $accessToken,
            'userid' => $userId
        ];
        $response = $this->request->request(API::$USER_GET, 'GET', $param);

        if ($response->isSuccess()) {
            return $response->getBody() ?? [];
        } else {
            throw new Exception($response->getError());
        }
    }

    /**
     * 获取成员ID列表
     * @param string $accessToken
     * @return mixed|string
     * @throws Exception
     */
    public function getUserListId(string $accessToken)
    {
        $getParam = [
            'access_token' => $accessToken
        ];

        $param = [
            "cursor" => "",
            "limit" => 10000
        ];
        $response = $this->request->request(API::$USER_LIST_ID . '?' . http_build_query($getParam), 'POST', $param);

        if ($response->isSuccess()) {
            return $response->getBody();
        } else {
            throw new Exception($response->getError());
        }
    }

    /**
     * 获取部门列表
     * @param string $accessToken
     * @param string $departmentId
     * @return mixed|string
     * @throws Exception
     */
    public function getDepartmentListId(string $accessToken, string $departmentId = '')
    {
        $getParam = [
            'access_token' => $accessToken,
            'id' => $departmentId
        ];

        if (!$departmentId) {
            unset($getParam['id']);
        }

        $response = $this->request->request(API::$DEPARTMENT_LIST_ID, 'GET', $getParam);

        if ($response->isSuccess()) {
            return $response->getBody();
        } else {
            throw new Exception($response->getError());
        }
    }

    /***
     * 获取访问用户身份
     * @param string $accessToken
     * @param string $code
     * @return mixed|string
     * @throws Exception
     */
    public function codeToUser(string $accessToken, string $code)
    {
        $getParam = [
            'access_token' => $accessToken,
            'code' => $code
        ];

        $response = $this->request->request(API::$GETUSERINFO, 'GET', $getParam);

        if ($response->isSuccess()) {
            return $response->getBody();
        } else {
            throw new Exception($response->getError());
        }

    }

    /**
     * 获取访问用户身份-第三方
     * @param string $suiteAccessToken
     * @param string $code
     * @return mixed|string
     * @throws Exception
     */
    public function codeToUser3rd(string $suiteAccessToken, string $code)
    {
        $getParam = [
            'suite_access_token' => $suiteAccessToken,
            'code' => $code
        ];

        $response = $this->request->request(API::$GETUSERINFO3RD, 'GET', $getParam);

        if ($response->isSuccess()) {
            return $response->getBody();
        } else {
            throw new Exception($response->getError());
        }

    }

    /**
     * 获取客户群详情
     * @param string $accessToken
     * @param string $chatId
     * @return mixed|string
     * @throws Exception
     */
    public function groupchat(string $accessToken, string $chatId)
    {
        $getParam = [
            'access_token' => $accessToken,
        ];
        $param = [
            'chat_id' => $chatId,
            'need_name' => 0
        ];

        $response = $this->request->request(API::$GROUPCHAT . '?' . http_build_query($getParam), 'POST', $param);

        if ($response->isSuccess()) {
            return $response->getBody()['group_chat'] ?? [];
        } else {
            throw new Exception($response->getError());
        }
    }

    /**
     * 图片上传
     * @param string $accessToken
     * @param $file
     * @return mixed|string
     * @throws Exception
     */
    public function uploadimg(string $accessToken, $file)
    {
        $getParam = [
            'access_token' => $accessToken,
        ];
        $param = [[
            'name' => 'filename',
            'filename' => $file,
            'contents' => Utils::tryFopen($file, 'r'),
            'headers' => [
                'Content-Type' => "<Content-type header>"
            ]
        ]];

        $response = $this->request->request(API::$UPLOADIMG . '?' . http_build_query($getParam), 'FORM', $param);

        if ($response->isSuccess()) {
            return $response->getBody()['url'] ?? '';
        } else {
            throw new Exception($response->getError());
        }
    }

    /**
     * 创建群发消息
     * @param string $accessToken
     * @param array $array
     * @return array|mixed|string
     * @throws Exception
     */
    public function addMsgTemplate(string $accessToken,array $array)
    {
        $getParam = [
            'access_token' => $accessToken,
        ];

        $response = $this->request->request(API::$MSGTEMPLATE . '?' . http_build_query($getParam), 'POST', $array);

        if ($response->isSuccess()) {
            return $response->getBody() ?? [];
        } else {
            throw new Exception($response->getError());
        }
    }


    /**
     * 获取会话记录
     * @param string $accessToken
     * @param string|null $cursor
     * @param string $limit
     * @param string|null $token
     * @return array|mixed|string
     * @throws Exception
     */
    public function syncMsg(string $accessToken,string $cursor = null ,string $limit = '1000',string $token = null)
    {
        $getParam = [
            'access_token' => $accessToken,
        ];

        $postParam = [
            'cursor' => $cursor,
            'token' => $token,
            'limit' => $limit,
        ];

        $postParam = array_filter($postParam);

        $response = $this->request->request(API::$SYNC_MSG . '?' . http_build_query($getParam), 'POST', $postParam);

        if ($response->isSuccess()) {
            return $response->getBody() ?? [];
        } else {
            throw new Exception($response->getError());
        }
    }
}
